package com.jiumi.api.service.impl;

import com.sun.jna.platform.win32.Netapi32Util;
import com.jiumi.api.service.ILoginApiService;
import com.jiumi.baseconfig.domain.BaseUser;
import com.jiumi.common.constant.Constants;
import com.jiumi.common.exception.ServiceException;
import com.jiumi.common.exception.user.UserPasswordNotMatchException;
import com.jiumi.common.utils.DateUtils;
import com.jiumi.common.utils.MessageUtils;
import com.jiumi.common.utils.SecurityUtils;
import com.jiumi.common.utils.StringUtils;
import com.jiumi.framework.manager.AsyncManager;
import com.jiumi.framework.manager.factory.AsyncFactory;
import com.jiumi.framework.security.context.AuthenticationContextHolder;
import com.jiumi.framework.web.service.TokenApiService;
import com.jiumi.framework.web.service.UserInfo;
import com.jiumi.baseconfig.service.IBaseUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lun.zhang
 * @create 2022/10/18 11:08
 */
@Service
public class LoginApiServiceImpl implements ILoginApiService {

    @Autowired
    private IBaseUserService userInfoService;

    @Resource(name = "authenticationManagerApi")
    private AuthenticationManager authenticationManager;

    @Autowired
    private TokenApiService tokenService;

    @Override
    public Map<String, Object> login(Map<String, Object> userInfo) {
        String username = String.valueOf(userInfo.get("openid"));
        String sessionKey = String.valueOf(userInfo.get("session_key"));
        String avatar = (null == userInfo.get("avatar")) ? "" : String.valueOf(userInfo.get("avatar"));
        String sex = (null == userInfo.get("sex")) ? "" : String.valueOf(userInfo.get("sex"));
        String nickName = (null == userInfo.get("nickName")) ? "" : String.valueOf(userInfo.get("nickName"));
        Authentication authentication = null;
        BaseUser user = userInfoService.selectBaseUserByUserName(username);
        if (StringUtils.isNull(user)) {
            //增加用户信息
            user = new BaseUser();
            user.setUserName(username);
            user.setPassword(SecurityUtils.encryptPassword("admin123"));
            userInfoService.insertBaseUser(user);
        }
        try {
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, "admin123"));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            } else {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new RuntimeException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        UserInfo loginUser = (UserInfo) authentication.getPrincipal();
        if (StringUtils.isNotNull(loginUser)) {
            //修改登录时间
            BaseUser u = new BaseUser();
            u.setLoginDate(DateUtils.getNowDate());
            loginUser.getUserInfo().setLoginDate(u.getLoginDate());
            u.setUserId(loginUser.getUserInfo().getUserId());
            userInfoService.updateBaseUser(user);
        }
        Map<String, Object> result = new HashMap<>();
        result.put(Constants.TOKEN, tokenService.createToken(loginUser));
        result.put("userInfo", loginUser.getUserInfo());
        result.put("sessionKey", sessionKey);
        return result;
    }

    @Override
    public String loginApp(String username, String password, String uuid)
    {
        // 用户验证
        Authentication authentication = null;
        try
        {
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
            AuthenticationContextHolder.setContext(authenticationToken);
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager.authenticate(authenticationToken);
        }
        catch (Exception e)
        {
            if (e instanceof BadCredentialsException)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
            else
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));
                throw new ServiceException(e.getMessage());
            }
        }
        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        UserInfo loginUser = (UserInfo) authentication.getPrincipal();
        //recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
    }
}
